package top.itbook.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;

/**
 * SHA256单向散列算法，256位散列算法为企业中应用比较多的之一，512由于位数较长，会损失一部分性能
 * 而256则因为其相对安全性且很难发生碰撞的原因被广泛使用。
 */
public class SHA256 extends Provider {
    private static SHA256 instance; // 本类对象
    final private static String salt = "@KingSHA256.top"; // 盐值

    private SHA256(String name, String versionStr, String info){
        super(name,versionStr,info);
    }

    /**
     * 获取本类实例化对象
     * @return SHA-256 散列算法对象
     */
    public static SHA256 getInstance(){
        if (instance == null){
            instance = new SHA256("King","0.1","SHA256位信息摘要算法，目前为止具有良好的安全性。");
        }
        return instance;
    }

    /**
     * SHA - 256 信息摘要算法
     * 不可逆加密，加密字符串
     * @param content 要获取摘要的字符串
     * @return 若成功获取摘要则返回十六进制字符串，若发生不可预见的错误则返回null
     */
    @Deprecated
    public String SHA256encryption(String content){
        MessageDigest messageDigest;
        String s = null; // 加密后的字符串
        try {
            messageDigest = MessageDigest.getInstance("SHA-256"); // 获取加密类实例化对象
            // 更新摘要
            messageDigest.update(content.getBytes());
            // 将要加密的字符串转换成哈希值
            byte[] resultBytes = messageDigest.digest();
            // 将信息转换成十六进制字符串
            s = convertString(resultBytes);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return s;
    }

    /**
     * SHA256加密算法(加盐) - 不可逆加密 - 加密字符串
     * @param content
     * @return
     */
    public String SHA256encryptionPLUS(String content){
        MessageDigest messageDigest;
        String s = null;
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            // 进行字符串拼接（加盐）
            content = content + salt;
            // 更新摘要
            messageDigest.update(content.getBytes());
            // 将要加密的字符串转换成哈希值
            byte[] digest = messageDigest.digest();
            // 将信息转化成十六进制字符串
            s = convertString(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return s;
    }

    // 将字节数组转换成十六进制字符串
    private String convertString(byte[] bytes){
        StringBuilder stringBuilder = new StringBuilder(bytes.length * 2);
        for (byte aByte : bytes) {
            stringBuilder.append(String.format("%02x",aByte & 0xff));
        }
        return stringBuilder.toString();
    }
}
